'use strict';

const uidObj = require('uni-id');
const {
	XMLParser
} = require("fast-xml-parser");
const db = uniCloud.database();
const {
	mainSpaceId
} = require('config-main-space')
exports.main = async (event, context) => {
	let response = {
		mpserverlessComposedResponse: true,
		statusCode: 200,
		headers: {
			'content-type': 'text/xml;charset=utf-8'
		},
		body: `<xml><return_code><![CDATA[FAILD]]></return_code><return_msg><![CDATA[异常回调]]></return_msg></xml>`
	};

	let data = event.body
	if (event.isBase64Encoded) {
		data = new Buffer(data, 'base64').toString();
	}

	const path = event.path;
	let res = {};

	let notifyType = 'payment';
	let payObj = {
		name: '微信支付',
		way: 'wxpay'
	};
	switch (path) {
		case '/':
		case '/wxpay':
		case '/wxpay-app':
		case '/wxpay-h5wx':
			const parser = new XMLParser();
			res = parser.parse(data);
			res = res.xml
			try {
				//特殊处理transaction_id
				let transaction_ids = data.split('<transaction_id><![CDATA[')
				if (transaction_ids.length > 0) {
					let transaction_id = transaction_ids[1].split("]]></transaction_id>")[0]
					res.transaction_id = transaction_id
				}
			} catch (e) {

			}

			break;
		case '/alipay':
		case '/alipay-app':
			var queryArr = data.split("&");
			queryArr.forEach(function(item) {
				var key = item.split("=")[0];
				var value = item.split("=")[1];
				res[key] = value;
			});
			res.total_fee = res.total_amount * 100
			res.transaction_id = res.trade_no
			payObj.name = '支付宝支付';
			payObj.way = 'alipay';
			break;
		default:
			break;
	}

	// 根据支付订单号获取订单数据
	// 根据创建订单用户ID获取用户数据
	// 记录用户充值金额、写入用户零钱
	// 发送零钱到账消息通知
	if (res && (res.return_code == 'SUCCESS' || res.result_code == 'SUCCESS' || res.trade_status ==
			'TRADE_SUCCESS') && notifyType == 'payment') {

		let outTradeNo = res.out_trade_no
		let totalFee = res.total_fee
		let transactionId = res.transaction_id
		let openid = res.openid

		// 根据支付订单号获取订单数据
		const orderRes = await db.collection('wmzmall-member-pay')
			.doc(outTradeNo)
			.get();

		const [orderPay] = orderRes.data;
		if (!orderPay) {
			uniCloud.logger.info(`订单[${outTradeNo}]不存在`);
			return response;
		}
		if (orderPay.pay_state != '待付款') {
			uniCloud.logger.info(`订单[${outTradeNo}]状态[${orderPay.pay_state}]`);
			return response;
		}

		const nowdate = Date.now();
		const ip = event.headers['x-real-ip'];

		// 优先将订单支付状态修改为待核实
		await db.collection('wmzmall-member-pay').doc(orderPay._id).update({
			version: db.command.inc(1),
			pay_state: '待核实',
			pay_notify: event,
			pay_no: transactionId,
			pay_openid: openid,
			ip,
			//yymm: ,
			//yymmdd: ,
			pay_time: nowdate
		});

		if (orderPay.pay_money * 100 != totalFee) {
			uniCloud.logger.info(`订单[${outTradeNo}]支付金额不一致，[${orderPay.pay_money * 100}] != [${totalFee}]`);
			return response;
		}

		// 创建订单用户ID
		const uid = orderPay.create_uid;
		let vip = orderPay.vip
		let entitlement_id = orderPay.entitlement_id
		// 根据创建订单用户ID获取用户数据
		const userRes = await db.collection('wmzmall-member')
			.doc(uid)
			.field({
				member_name: true,
				member_mobile: true,
				member_type: true,
				member_weixin: true,
				member_alipay: true,
				member_amount: true,
				app_id: true,
				shop_id: true
			})
			.get();
		if (!(userRes.data && userRes.data.length == 1)) {
			uniCloud.logger.info(`订单[${outTradeNo}]对应的用户不存在`);
			return response;
		}
		// 用户
		const user = userRes.data[0];
		const uname = user.member_name;
		if (vip === '1') {
			await db.collection('wmzmall-member').doc(uid).update({
				is_plus: '付费会员',
				plus_time: new Date().getTime()
			});
		}
		if (entitlement_id) {
			let entitlementOrder = await db.collection('wmz-entitlement').doc(entitlement_id).get()
			entitlementOrder = entitlementOrder.data[0]
			let coupon_data = entitlementOrder.coupon_data
			for (var i in coupon_data) {
				coupon_data[i].goods_type = "mobile_coupon"
				coupon_data[i].order_id = uid
				coupon_data[i].user_id = uid
				coupon_data[i].status = '未使用'
				coupon_data[i].app_id = user.app_id
				coupon_data[i].create_time = new Date().getTime()
				let cRes = await db.collection('wmz-entitlement-coupon').add(coupon_data[i])
			}
		}
		// 开启事务
		const dbtran = await db.startTransaction();

		try {

			// 修改订单支付数据
			await dbtran.collection('wmzmall-member-pay').doc(outTradeNo).update({
				version: db.command.inc(1),
				pay_state: '已付款',
				pay_notify: event,
				pay_no: transactionId,
				pay_openid: openid,
				pay_way: payObj.name,
				ip,
				//yymm: ,
				//yymmdd: ,
				pay_time: nowdate
			});

			// 记录用户充值金额、写入用户零钱
			await dbtran.collection('wmzmall-member').doc(uid).update({
				member_amount: db.command.inc(orderPay.get_money * 100)
			});
			let content = `通过${payObj.name}充值+${orderPay.pay_money}获得+${orderPay.get_money}`;
			if (user.member_amount < 0) {
				content = `快递费差额补正充值+${orderPay.pay_money}`;
			}
			const payLogRes = await dbtran.collection('wmzmall-member-money-log').doc(outTradeNo).get();
			const payLog = payLogRes.data;
			if (payLog && payLog._id) {
				await dbtran.collection('wmzmall-member-money-log').doc(payLog._id).update({
					user_uid: uid,
					order_id: outTradeNo,
					money: orderPay.pay_money,
					money_fmt: '+' + orderPay.get_money,
					source: payObj.name,
					state: '已付款',
					type: '充值',
					remark: content,
					ip: ip,
					is_delete: 0,
					create_uid: uid,
					create_uname: uname,
					create_time: nowdate
				});
			} else {
				await dbtran.collection('wmzmall-member-money-log').doc(outTradeNo).set({
					user_uid: uid,
					order_id: outTradeNo,
					money: orderPay.pay_money,
					money_fmt: '+' + orderPay.get_money,
					source: payObj.name,
					state: '已付款',
					type: '充值',
					remark: content,
					ip: ip,
					is_delete: 0,
					create_uid: uid,
					create_uname: uname,
					create_time: nowdate
				});
			}

			// 提交事务
			await dbtran.commit();
			let title = '收款';
			let cate = '充值';
			let type = 0;
			let appId = user.app_id;
			let auto_deliver
			let appletInfoData = await db.collection('wmz-applet-info').doc(appId).get()
			appletInfoData = appletInfoData.data[0]
			if (appletInfoData && appletInfoData.auto_deliver) {
				auto_deliver = appletInfoData.auto_deliver
			}
			let shopId = user.shop_id;
			let orderNo = transactionId;
			let way = payObj.name;
			let payMoney = orderPay.pay_money;
			let shopie = {
				app_id: appId,
				shop_id: shopId,
				order_no: orderNo,
				title: title,
				cate: cate,
				type: type,
				way: way,
				money: payMoney*100,
				creator_id: uid,
				create_time: new Date().getTime(),
				auto_deliver:auto_deliver
			};
			let addShopieResult = await db.collection('wmzmall-shopie').add(shopie);
			let tdb = uniCloud.database({
				provider: 'tencent',
				spaceId: mainSpaceId
			})
			await tdb.collection('wmzmall-shopie').add(shopie)
		} catch (e) {
			await db.collection('wmzmall-member-pay').doc(orderPay._id).update({
				version: db.command.inc(1),
				pay_state: '待付款'
			});

			// 事务回滚
			await dbtran.rollback();
			uniCloud.logger.info(`订单[${outTradeNo}]支付回调处理异常 ${e.message}`);
			return response;
		}

		if (payObj.way == 'wxpay') {
			response.body =
				`<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>`;
		} else if (payObj.way = 'alipay') {
			response.headers['content-type'] = 'text/plain';
			response.body = 'success';
		}
	}

	if (notifyType == 'refund') {
		if (payObj.way = 'alipay') {
			response.headers['content-type'] = 'text/plain';
			response.body = 'success';
		}
	}

	uniCloud.logger.info(res);
	uniCloud.logger.info(response);

	return response;
};

/**
 * 将 UTC+0 转换为 UTC+8
 */
function toDateUTC8(date) {
	// 小时 UTC+0 转换为 UTC+8
	date.setHours(date.getHours() + 8);
	return date;
}


const uDelay = async (sec) => {
	return new Promise((c1, c2) => {
		console.log('uDelay sec', sec);
		setTimeout(() => {
			c1();
			console.log('uDelay sec success', sec);
		}, sec * 1000);
	});
}